home *** CD-ROM | disk | FTP | other *** search
/ Amiga Packmags / Source, The - Issue 5 (1993)(Epsilon)[WB].zip / Source, The - Issue 5 (1993)(Epsilon)[WB].adf / Source / Vectors / sirds.lha / sirds.c next >
C/C++ Source or Header  |  1993-04-12  |  9KB  |  245 lines

  1. /*******************************************************************/
  2. /*                                                                 */
  3. /*    sirds.c         - by Henry Watson -        Mar. 30, 1993      */
  4. /*                                                                 */
  5. /*    This program takes an input image in depth map format and    */
  6. /* generates a Single Image Random Dot Stereogram (SIRDS) image    */
  7. /* as output.  Two fusion triangles are printed out at the top of  */
  8. /* the image to aid in seeing the hidden 3-D image.  The number    */
  9. /* of disparity levels to be generated in the output image may     */
  10. /* also be specified but defaults to 11.                           */
  11. /*                                                                 */
  12. /* =============================================================== */
  13. /*                                                                 */
  14. /*    To run, do                                                   */
  15. /*    % sirds <input_image> <output_image> [disparity_levels]      */
  16. /*                                                                 */
  17. /*******************************************************************/
  18.  
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <hipl_format.h>    /* include HIPS definitions */
  22. #include <math.h>
  23.  
  24. #define NODEBUG 0
  25. #define DEBUG 1
  26.  
  27. #define    PIXEL_FORMAT PFBYTE    /* set the pixel format for the HIPS routines */
  28. typedef byte    PIXEL_TYPE;    /* set the pixel type for the program to use */
  29.  
  30. #define NUM_GRAY_LEVELS 256
  31. #define WHITE (PIXEL_TYPE)255
  32. #define BLACK (PIXEL_TYPE)0
  33.  
  34. #define MAXSIZE 512        /* maximum dimension to image array */
  35.                 /* and thus input image as well     */
  36.  
  37. #define IMAGE_OFFSET_PCT 0.30    /* stereo image offset in terms of percent */
  38.  
  39. #define MAXSIRDSWIDTH 665    /* maximum width of final SIRDS image  */
  40.                 /* MAXSIZE * (IMAGE_OFFSET_PCT+1)      */
  41.  
  42. #define DOTHEIGHT 9        /* height of the fusion dots at the page top */
  43.  
  44. #define DISPARITY_LEVELS 11    /* default number of discrete levels of      */
  45.                 /* disparity.  Ranges from -d/2 to 0 to +d/2 */
  46.                 /* (ie. number of levels of depth)           */
  47.  
  48. #define    frame_number 1        /* constant frame number for HIPS routines */
  49.  
  50.  
  51.  
  52.  
  53. /*******************************************************************/
  54. /* main()                                                          */
  55. /*                                                                 */
  56. /*    The sequence of processing steps involves:                   */
  57. /*    (1) interpreting the command line                            */
  58. /*    (2) reading the header                                       */
  59. /*    (3) validating the input size, format, etc.                  */
  60. /*    (4) reading image frame                                      */
  61. /*    (5) performing image processing algorithms                   */
  62. /*    (6) forming the output image                                 */
  63. /*    (7) writing to file                                          */
  64. /*                                                                 */
  65. /*******************************************************************/
  66.  
  67. void    main( argc, argv )
  68.  
  69. int    argc;
  70. char    **argv;
  71. {
  72.  
  73. char        *input_filename, *output_filename;
  74. FILE        *input_fp, *output_fp;
  75. struct header    input_header, output_header;
  76. PIXEL_TYPE    Object[MAXSIZE][MAXSIZE],
  77.         Sirds[MAXSIZE][MAXSIRDSWIDTH];
  78. byte        *pixel_ptr;
  79. int        rowmax, colmax,
  80.         row, col,
  81.         right_image_start,
  82.         sirdswidth, sirdsheight,
  83.         disparity_levels = DISPARITY_LEVELS,
  84.         disparity_offset = DISPARITY_LEVELS/-2,
  85.         disparity;
  86.  
  87.    /* INTERPRETING THE COMMAND LINE */
  88.  
  89.    if( (argc<3) || (argc>4) )
  90.    {
  91.       printf("Usage:  %s <input_image> <output_image> [disparity_levels]\n", argv[0]);
  92.       exit(0);
  93.    }
  94.    input_filename = argv[1];            /* name of input file  */
  95.    output_filename = argv[2];           /* name of output file */
  96.  
  97.    if( argc>3 )
  98.    {
  99.       disparity_levels = atoi( argv[3] );
  100.       disparity_offset = disparity_levels/-2;
  101.  
  102.       if( disparity_levels < 2 )
  103.       {
  104.          printf("Invalid number of disparity levels specified.\n");
  105.          printf("Value must be 2 or greater.  Default is %d.\n",
  106.         DISPARITY_LEVELS);
  107.          exit(-1);
  108.       }
  109.    }
  110.  
  111.  
  112.    /* READING THE HEADER */
  113.  
  114.    /* open the file and read header */
  115.    input_fp = hfopenr( input_filename );
  116.    fread_hdr_a( input_fp, &input_header, input_filename );
  117.  
  118.    /* copy image x and y dimensions */
  119.    rowmax = input_header.orows;
  120.    colmax = input_header.ocols;
  121.  
  122.  
  123.    /* VALIDATING THE INPUT SIZE, FORMAT, ETC. */
  124.  
  125.    if( input_header.pixel_format != PIXEL_FORMAT )
  126.    {
  127.       printf("This program only handles pixel format %d.\n",PIXEL_FORMAT);
  128.       printf("Program aborted.\n");
  129.       exit(-1);
  130.    }
  131.    else if( rowmax>MAXSIZE || colmax>MAXSIZE )
  132.    {
  133.       printf("Input image too large.  Maximum size is %d X %d.\n",MAXSIZE,MAXSIZE);
  134.       exit(-1);
  135.    }
  136.    else
  137.    {
  138.       printf("%d X %d %s is being read.\n", rowmax, colmax, input_filename);
  139.    }
  140.  
  141.  
  142.    /* READING IMAGE FRAME */
  143.  
  144.    /* read the image frame into a buffer */
  145.    fread_image( input_fp, &input_header, frame_number, input_filename );
  146.  
  147.    /* reformat the buffer into an array; */
  148.    /* image is pointed to by input_header.image */
  149.    pixel_ptr = input_header.image;
  150.    for( row=0; row < rowmax; row++ )
  151.    {
  152.       pixel_ptr = input_header.image + (row*colmax*input_header.sizepix);
  153.       for( col=0; col < colmax; col++ )
  154.      Object[row][col] = (PIXEL_TYPE) *pixel_ptr++;
  155.    }
  156.  
  157.  
  158.  
  159.    /* PERFORMING IMAGE PROCESSING ALGORITHM */
  160.  
  161.    /* determine the right stereo image position and the final image size */
  162.  
  163.    right_image_start = IMAGE_OFFSET_PCT * colmax;
  164.  
  165.    sirdswidth = colmax + right_image_start;
  166.    sirdsheight = rowmax;
  167.  
  168.  
  169.    /* fill the SIRDS image with random binary values */
  170.  
  171.    for( row=0; row < sirdsheight; row++ )
  172.       for( col=0; col < sirdswidth; col++ )
  173.          Sirds[row][col] = ( (rand() > RAND_MAX/2) ? WHITE : BLACK );
  174.  
  175.  
  176.    /* perform pixel shifts based on input Object image */
  177.  
  178.    for( row=0; row < rowmax; row++ )
  179.       for( col=0; col < colmax; col++ )
  180.       {
  181.          /* assign high (+d) disparity to low intensities (ie. dark = far) */
  182.          /* and low disparity (-d) to high intensities (ie. bright = near) */
  183.  
  184.          disparity = (NUM_GRAY_LEVELS-Object[row][col]-1) * disparity_levels
  185.                      / NUM_GRAY_LEVELS + disparity_offset;
  186.  
  187.          /* make sure the destination pixel position is in range */
  188.          if( right_image_start+col+disparity < sirdswidth )
  189.             Sirds[row][right_image_start+col+disparity] = Sirds[row][col];
  190.       }
  191.  
  192.  
  193.    /* FORMING THE OUTPUT IMAGE */
  194.  
  195.    /* initialize a header from scratch and allocate an image for the header */
  196.  
  197.    init_hdr_alloc( &output_header, "", "", frame_number, "",
  198.                    sirdsheight+DOTHEIGHT, sirdswidth, PIXEL_FORMAT, 1, "");
  199.  
  200.    /*  output_header - address of the HIPS header                            */
  201.    /*  ""            - original sequence name for documentation purposes     */
  202.    /*  ""            - new sequence name for documentation purpose           */
  203.    /*  frame_number  - only one frame is required here                       */
  204.    /*  ""            - date for documentation purposes                       */
  205.    /*  sirdsheight   - number of rows                                        */
  206.    /*  sirdswidth    - number of columns                                     */
  207.    /*  PIXEL_FORMAT  - code for pixel format                                 */
  208.    /*  1             - number of color planes                                */
  209.    /*  ""            - the sequence description for documentation purpose    */
  210.  
  211.  
  212.    /* write the image array to the output header */
  213.  
  214.    pixel_ptr = output_header.image;
  215.  
  216.    /* first write out a pair of fusion dots for ease of viewing */
  217.    /* (ie. generate the two funky looking triangles at the top) */
  218.  
  219.    for( row=0; row < DOTHEIGHT; row++ )
  220.       for( col=0; col < sirdswidth; col++ )
  221.      if( ( col>=(colmax/2-DOTHEIGHT+1+row)
  222.            && col<=(colmax/2+DOTHEIGHT-1-row) )
  223.       || ( col>=(right_image_start+colmax/2-DOTHEIGHT+1+row)
  224.            && col<=(right_image_start+colmax/2+DOTHEIGHT-1-row) ) )
  225.         *pixel_ptr++ = (byte) BLACK;
  226.      else
  227.         *pixel_ptr++ = (byte) WHITE;
  228.  
  229.    /* second, write out the SIRDS array */
  230.  
  231.    for( row=0; row < sirdsheight; row++ )
  232.       for( col=0; col < sirdswidth; col++ )
  233.      *pixel_ptr++ = (byte) Sirds[row][col];
  234.  
  235.  
  236.    /* WRITE TO FILE */
  237.  
  238.    printf("%d X %d %s is being written.\n", sirdsheight, sirdswidth,
  239.           output_filename);
  240.    output_fp = ffopen( output_filename, "w" );
  241.    fwrite_header( output_fp, &output_header, output_filename );
  242.    fwrite_image( output_fp, &output_header, 1, output_filename );
  243.    fclose( output_fp );
  244. }
  245.